package luongvd.appdownload.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class ServerConnectionUtils {

	public static String json;
	public static JSONObject retObj;
	public static int CONNECT_TO_SERVER_MESSAGE_ERROR = -1,
			CONNECT_TO_SERVER_MESSAGE_SUCCESSFUL = 1;
	public static int SERVER_CONNECT_TIMEOUT = 30 * 1000;// 30S

	public enum RequestMethod {
		GET, POST, PUT, DELETE
	}

	public static Object getFromURL(String url, List<NameValuePair> params,
			Handler handler, Type retType) {
		return sendHttpRequest(url, params, RequestMethod.GET, handler, retType);
	}

	public static Object postToURL(String BASE_URL, List<NameValuePair> params,
			Handler handler, Type retType) {
		return sendHttpRequest(BASE_URL, params, RequestMethod.POST, handler,
				retType);
	}

	public static Object putToURL(String url, List<NameValuePair> params,
			Handler handler, Type retType) {
		return sendHttpRequest(url, params, RequestMethod.PUT, handler, retType);
	}

	public static Object deleteFromURL(String url, List<NameValuePair> params,
			Handler handler, Type retType) {
		return sendHttpRequest(url, params, RequestMethod.DELETE, handler,
				retType);
	}

	public static Object sendHttpRequest(String url,
			List<NameValuePair> params, RequestMethod method, Handler handler,
			Type retType) {
		if (url == null || url.trim().length() == 0) {
			throw new IllegalArgumentException();
		}
		HttpClient httpClient = new DefaultHttpClient();
		HttpUriRequest reqMethod = null;
		HttpParams paramsHTTP = httpClient.getParams();
		HttpConnectionParams.setConnectionTimeout(paramsHTTP,
				SERVER_CONNECT_TIMEOUT);
		HttpConnectionParams.setSoTimeout(paramsHTTP, SERVER_CONNECT_TIMEOUT);
		switch (method) {
		case GET:
			reqMethod = new HttpGet(buildUrlWithQueryString(url, params));
			break;
		case POST:
			UrlEncodedFormEntity postEnt = createUrlEncodedFormEntity(params);
			reqMethod = new HttpPost(url);
			((HttpPost) reqMethod).setEntity(postEnt);
			break;
		case PUT:
			UrlEncodedFormEntity putEnt = createUrlEncodedFormEntity(params);
			reqMethod = new HttpPut(url);
			((HttpPut) reqMethod).setEntity(putEnt);
			break;
		case DELETE:
			reqMethod = new HttpDelete(buildUrlWithQueryString(url, params));
			break;
		}
		Log.i("Chauffer", reqMethod.getURI().toString());
		try {
			HttpResponse resp = httpClient.execute(reqMethod);
			if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(resp.getEntity().getContent()));
				StringBuffer buffer = new StringBuffer();
				String line = null;
				while ((line = reader.readLine()) != null) {
					buffer.append(line + "\n");
				}
				String json = buffer.toString();
				try {
					retObj = new JSONObject(json);
				} catch (JSONException e) {
				}
				// Call back
				if (handler != null) {
					Message msg = new Message();
					msg.arg1 = CONNECT_TO_SERVER_MESSAGE_SUCCESSFUL;
					msg.obj = retObj;
					handler.sendMessage(msg);
				}
			} else {
				sendErrorMessage(handler,
						"Error authenticating" + resp.getStatusLine());
			}
		} catch (IOException ex) {
			sendErrorMessage(handler, ex.getMessage());

		} catch (Exception ex) {
			if (handler != null) {
				sendErrorMessage(handler, ex.getMessage());
			}
		}
		return retObj;
	}

	//Run background
	public static Thread performOnBackgroundThread(final Runnable runnable) {
		final Thread t = new Thread() {
			@Override
			public void run() {
				try {
					runnable.run();
				} finally {

				}
			}
		};
		t.start();
		return t;
	}

	public static void sendErrorMessage(Handler handler, String msg) {
		if (handler != null) {
			Message errorMsg = new Message();
			errorMsg.arg1 = CONNECT_TO_SERVER_MESSAGE_ERROR;
			errorMsg.obj = msg;
			handler.sendMessage(errorMsg);
		}
	}

	public static String buildUrlWithQueryString(String url,
			List<NameValuePair> params) {

		String paramString = URLEncodedUtils.format(params, "utf-8");
		return url + "?" + paramString;
	}

	public static UrlEncodedFormEntity createUrlEncodedFormEntity(
			List<NameValuePair> params) {
		UrlEncodedFormEntity ent;
		try {
			ent = new UrlEncodedFormEntity(params, HTTP.UTF_8);
		} catch (UnsupportedEncodingException e) {
			throw new AssertionError();
		}
		return ent;
	}
}
